package com.fastbee.iot.tdengine.service.impl;

import cn.hutool.core.date.DateUtil;
import com.fastbee.common.utils.DateUtils;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.iot.domain.Device;
import com.fastbee.iot.domain.DeviceLog;
import com.fastbee.iot.model.*;
import com.fastbee.iot.model.param.DataCenterParam;
import com.fastbee.iot.tdengine.service.ILogService;
import com.fastbee.iot.tdengine.config.TDengineConfig;
import com.fastbee.iot.tdengine.dao.TDDeviceLogDAO;
import com.fastbee.iot.tdengine.service.model.TdLogDto;
import com.fastbee.iot.util.SnowflakeIdWorker;
import org.springframework.context.ApplicationContext;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 类名: TdengineLogServiceImpl
 * 描述: TDengine存储日志数据实现类
 * 时间: 2022/5/22,0022 13:38
 * 开发人: admin
 */
public class TdengineLogServiceImpl implements ILogService {

    private ApplicationContext applicationContext;

    private TDDeviceLogDAO tdDeviceLogDAO;

    private TDengineConfig tDengineConfig;

    private SnowflakeIdWorker snowflakeIdWorker;

    private String dbName;

    public TdengineLogServiceImpl(TDengineConfig _tDengineConfig, TDDeviceLogDAO _tdDeviceLogDAO) {
        this.tdDeviceLogDAO = _tdDeviceLogDAO;
        this.tDengineConfig = _tDengineConfig;
        snowflakeIdWorker = new SnowflakeIdWorker(1);
        this.dbName = _tDengineConfig.getDbName();
    }

    /***
     * 新增设备日志
     * @return
     */
    @Override
    public int saveDeviceLog(DeviceLog deviceLog) {
        long logId = snowflakeIdWorker.nextId();
        deviceLog.setLogId(logId);
        return tdDeviceLogDAO.save(dbName, deviceLog);
    }

    /**
     * 批量保存日志
     */
    @Override
    public int saveBatch(TdLogDto dto) {
        return tdDeviceLogDAO.saveBatch(dbName, dto);
    }

    /***
     * 设备属性、功能、事件和监测数据总数
     * @return
     */
    @Override
    public DeviceStatistic selectCategoryLogCount(Device device) {
        DeviceStatistic statistic = new DeviceStatistic();
        Long property = tdDeviceLogDAO.selectPropertyLogCount(dbName, device);
        Long function = tdDeviceLogDAO.selectFunctionLogCount(dbName, device);
        Long event = tdDeviceLogDAO.selectEventLogCount(dbName, device);
        Long monitor = tdDeviceLogDAO.selectMonitorLogCount(dbName, device);
        statistic.setPropertyCount(property == null ? 0 : property);
        statistic.setFunctionCount(function == null ? 0 : function);
        statistic.setEventCount(event == null ? 0 : event);
        statistic.setMonitorCount(monitor == null ? 0 : monitor);
        return statistic;
    }

    /***
     * 日志列表
     * @return
     */
    @Override
    public List<DeviceLog> selectDeviceLogList(DeviceLog deviceLog) {
        return tdDeviceLogDAO.selectDeviceLogList(dbName, deviceLog);
    }

    /***
     * 监测数据列表
     * @return
     */
    @Override
    public List<MonitorModel> selectMonitorList(DeviceLog deviceLog) {
        if (deviceLog.getIdentity() != null) {
            deviceLog.setIdentity("%" + deviceLog.getIdentity() + "%");
        }
        return tdDeviceLogDAO.selectMonitorList(dbName, deviceLog);
    }

    /***
     * 根据设备ID删除设备日志
     * @return
     */
    @Override
    public int deleteDeviceLogByDeviceNumber(String deviceNumber) {
        return tdDeviceLogDAO.deleteDeviceLogByDeviceNumber(dbName, deviceNumber);
    }

    /**
     * 查询历史数据
     * is_Montor=1 或 is_history=1
     */
    @Override
    public Map<String, List<HistoryModel>> selectHistoryList(DeviceLog deviceLog) {
        List<HistoryModel> historyList = tdDeviceLogDAO.selectHistoryList(dbName, deviceLog);
        return historyList.stream().collect(Collectors.groupingBy(HistoryModel::getIdentity));
    }

    @Override
    public List<HistoryModel> listHistory(DeviceLog deviceLog) {
        // 8时区问题
//        if (StringUtils.isNotEmpty(deviceLog.getBeginTime())) {
//            LocalDateTime localDateTime = DateUtils.toLocalDateTime(deviceLog.getBeginTime(), DateUtils.YYYY_MM_DD_HH_MM_SS);
//            deviceLog.setBeginTime(DateUtils.localDateTimeToStr(localDateTime.minusHours(8), DateUtils.YYYY_MM_DD_HH_MM_SS));
//        }
//        if (StringUtils.isNotEmpty(deviceLog.getEndTime())) {
//            LocalDateTime localDateTime = DateUtils.toLocalDateTime(deviceLog.getEndTime(), DateUtils.YYYY_MM_DD_HH_MM_SS);
//            deviceLog.setEndTime(DateUtils.localDateTimeToStr(localDateTime.minusHours(8), DateUtils.YYYY_MM_DD_HH_MM_SS));
//        }
        List<HistoryModel> historyModelList = tdDeviceLogDAO.listHistory(dbName, deviceLog);
        for (HistoryModel historyModel : historyModelList) {
            historyModel.setTime(DateUtils.dateRemoveMs(historyModel.getTime()));
        }
        return historyModelList;
    }

    @Override
    public List<HistoryModel> listhistoryGroupByCreateTime(DeviceLog deviceLog) {
        return tdDeviceLogDAO.listhistoryGroupByCreateTime(dbName, deviceLog);
    }

    @Override
    public List<String> selectStatsValue(DeviceLog deviceLog) {
        return tdDeviceLogDAO.selectStatsValue(dbName, deviceLog);
    }

    @Override
    public List<ThingsModelLogCountVO> countThingsModelInvoke(DataCenterParam dataCenterParam) {
        return tdDeviceLogDAO.countThingsModelInvoke(dbName, dataCenterParam);
    }

    public DeviceLog selectLastReport(DeviceLog deviceLog) {
        return null;
    }

    /**
     * 计算电量差值
     * @param start
     * @param end
     * @return
     */
    public BigDecimal getSubValue(String start,String end) {
        return (new BigDecimal(end.split("/")[2]).subtract(new BigDecimal(start.split("/")[2])));
    }

    /**
     * 首页园区能耗统计
     * @return
     */
    @Override
    public List<CommonStatisVo> selectEnergyConsumptionByMonthList(List<String> serialNumbers){
        Date dateNow = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dateNow);
        int year = calendar.get(Calendar.YEAR);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        List<CommonStatisVo> commonStatisVos = new ArrayList<>();
        DeviceLog deviceLog = new DeviceLog();
        Map params = new HashMap<>();
        params.put("beginTime", (year-1)+"-12-31 08:00:00");
        params.put("endTime", year+"-12-31 23:59:59");
        deviceLog.setParams(params);

        deviceLog.setIdentity("ActiveEnergy");
        List<EnergyConsumptionVo> energyConsumptionVos = tdDeviceLogDAO.selectRealEnergyMonitiorByYear(serialNumbers,deviceLog);

        deviceLog.setIdentity("ele");
        List<EnergyConsumptionEleVo> energyConsumptionEleVos = tdDeviceLogDAO.selectRealEnergyMonitiorEleByYear(serialNumbers,deviceLog);
        Map<String,BigDecimal> elaValueMap = new HashMap<>();
        if(energyConsumptionEleVos.size() > 0){
            Map<Timestamp,List<EnergyConsumptionEleVo>> elaMap = energyConsumptionEleVos.stream().collect(Collectors.groupingBy(EnergyConsumptionEleVo::getDateEnd));
            for (Timestamp timestamp : elaMap.keySet()) {
                List<EnergyConsumptionEleVo> dataList = elaMap.get(timestamp);
                BigDecimal value = BigDecimal.ZERO;
                for (EnergyConsumptionEleVo energyConsumptionEleVo : dataList) {
                    if(StringUtils.isBlank(energyConsumptionEleVo.getEnergyValueStart()) || StringUtils.isBlank(energyConsumptionEleVo.getEnergyValueEnd())){
                        continue;
                    }
                    value = value.add(getSubValue(energyConsumptionEleVo.getEnergyValueStart(),energyConsumptionEleVo.getEnergyValueEnd()));
                }
                String formattedDate = formatter.format(timestamp);
                LocalDate date = LocalDate.parse(formattedDate);
                elaValueMap.put(date.getMonthValue()+"月",value.setScale(2,RoundingMode.HALF_UP));
            }
        }

        if (null != energyConsumptionVos && energyConsumptionVos.size() > 0) {
            energyConsumptionVos.stream().forEach(d -> {
                CommonStatisVo commonStatisVo = new CommonStatisVo();
                String formattedDate = formatter.format(d.getDateEnd());
                LocalDate date = LocalDate.parse(formattedDate);
                System.out.println("年的维度统计"+date);
                if(date.getYear() == year){
                    String key = date.getMonthValue()+"月";
                    BigDecimal value = d.getEnergyValue();
                    commonStatisVo.setName(key);
                    commonStatisVo.setValueSort(date.getMonthValue());
                    if(elaValueMap.get(key) != null){
                        value = value.add(elaValueMap.get(key));
                    }
                    commonStatisVo.setValue(value.setScale(2,RoundingMode.HALF_UP));
                    if(date.getYear() == year){
                        commonStatisVos.add(commonStatisVo);
                    }
                }
            });
        }else{
            for(int i=1;i<=12;i++){
                CommonStatisVo commonStatisVo = new CommonStatisVo();
                String key = i+"月";
                BigDecimal value = BigDecimal.ZERO;
                commonStatisVo.setName(key);
                commonStatisVo.setValueSort(i);
                if(elaValueMap.get(key) != null){
                    value = value.add(elaValueMap.get(key));
                }
                commonStatisVo.setValue(value);
                commonStatisVos.add(commonStatisVo);
            }
        }
        commonStatisVos.sort((p1, p2) -> Integer.compare(p1.getValueSort(), p2.getValueSort()));
        return commonStatisVos;
    }

    /**
     * 能耗实时监控
     * @addressId 设备所属地址ID（1：2楼营业厅，2：8楼机房，3：9楼机房）
     * @typeId 1:年，2：月，3：日，4：近七年
     * @serialNumbers 设备编号集合
     * @return
     */
    @Override
    public RealEnergyMonitiorVo selectRealEnergyMonitiorEleFour(Integer typeId,List<String> serialNumbers,Date dateNow){
        RealEnergyMonitiorVo realEnergyMonitiorVo = new RealEnergyMonitiorVo();
        if(dateNow == null){
            dateNow = new Date();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dateNow);
        Integer year = calendar.get(Calendar.YEAR);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        List<CommonStatisVo> commonStatisVos = new ArrayList<>();
        DeviceLog deviceLog = new DeviceLog();
        deviceLog.setIdentity("ele");

        Map params = new HashMap<>();
        params.put("beginTime", (year-7)+"-01-01 00:00:00");
        params.put("endTime", year+"-12-31 23:59:59");
        deviceLog.setParams(params);
        List<EnergyConsumptionEleVo> energyConsumptionVos = tdDeviceLogDAO.selectRealEnergyMonitiorEleByYearFour(serialNumbers,deviceLog);
        if(energyConsumptionVos.size() > 0){
            Map<Timestamp,List<EnergyConsumptionEleVo>> elaMap = energyConsumptionVos.stream().collect(Collectors.groupingBy(EnergyConsumptionEleVo::getDateEnd));
            for (Timestamp timestamp : elaMap.keySet()) {
                List<EnergyConsumptionEleVo> dataList = elaMap.get(timestamp);
                BigDecimal value = BigDecimal.ZERO;
                for (EnergyConsumptionEleVo energyConsumptionEleVo : dataList) {
                    if(StringUtils.isBlank(energyConsumptionEleVo.getEnergyValueStart()) || StringUtils.isBlank(energyConsumptionEleVo.getEnergyValueEnd())){
                        continue;
                    }
                    value = value.add(getSubValue(energyConsumptionEleVo.getEnergyValueStart(),energyConsumptionEleVo.getEnergyValueEnd()));
                }
                CommonStatisVo commonStatisVo = new CommonStatisVo();
                String formattedDate = formatter.format(timestamp);
                LocalDate date = LocalDate.parse(formattedDate);
                if(date.getYear() <= year){
                    commonStatisVo.setName(date.getYear()+"");
                    commonStatisVo.setValueSort(date.getYear());
                    commonStatisVo.setValue(value);
                    commonStatisVos.add(commonStatisVo);
                }
            }
        }else{
            for(int i=year-7;i<=year;i++){
                CommonStatisVo commonStatisVo = new CommonStatisVo();
                commonStatisVo.setName(i+"");
                commonStatisVo.setValueSort(i);
                commonStatisVo.setValue(BigDecimal.ZERO);
                commonStatisVos.add(commonStatisVo);
            }
        }
        realEnergyMonitiorVo.setCommonStatisVoList(commonStatisVos);
        realEnergyMonitiorVo.getCommonStatisVoList().sort((p1, p2) -> Integer.compare(p1.getValueSort(), p2.getValueSort()));
        return realEnergyMonitiorVo;
    }

    /**
     * 能耗实时监控
     * @addressId 设备所属地址ID（1：2楼营业厅，2：8楼机房，3：9楼机房）
     * @typeId 1:年，2：月，3：日，4：近七年
     * @serialNumbers 设备编号集合
     * @return
     */
    @Override
    public RealEnergyMonitiorVo selectRealEnergyMonitiorFour(Integer typeId,List<String> serialNumbers,Date dateNow){
        RealEnergyMonitiorVo realEnergyMonitiorVo = new RealEnergyMonitiorVo();
        if(dateNow == null){
            dateNow = new Date();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dateNow);
        Integer year = calendar.get(Calendar.YEAR);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        List<CommonStatisVo> commonStatisVos = new ArrayList<>();
        DeviceLog deviceLog = new DeviceLog();
        deviceLog.setIdentity("ActiveEnergy");

        Map params = new HashMap<>();
        params.put("beginTime", (year-7)+"-01-01 00:00:00");
        params.put("endTime", year+"-12-31 23:59:59");
        deviceLog.setParams(params);
        List<EnergyConsumptionVo> energyConsumptionVos = tdDeviceLogDAO.selectRealEnergyMonitiorFour(serialNumbers,deviceLog);
        if (null != energyConsumptionVos && energyConsumptionVos.size() > 0) {
            energyConsumptionVos.stream().forEach(d -> {
                CommonStatisVo commonStatisVo = new CommonStatisVo();
                String formattedDate = formatter.format(d.getDateEnd());
                LocalDate date = LocalDate.parse(formattedDate);
                if(date.getYear() <= year){
                    commonStatisVo.setName(date.getYear()+"");
                    commonStatisVo.setValueSort(date.getYear());
                    commonStatisVo.setValue(d.getEnergyValue());
                    commonStatisVos.add(commonStatisVo);
                }
            });
        }else{
            for(int i=year-7;i<=year;i++){
                CommonStatisVo commonStatisVo = new CommonStatisVo();
                commonStatisVo.setName(i+"");
                commonStatisVo.setValueSort(i);
                commonStatisVo.setValue(BigDecimal.ZERO);
                commonStatisVos.add(commonStatisVo);
            }
        }
        realEnergyMonitiorVo.setCommonStatisVoList(commonStatisVos);
        realEnergyMonitiorVo.getCommonStatisVoList().sort((p1, p2) -> Integer.compare(p1.getValueSort(), p2.getValueSort()));
        return realEnergyMonitiorVo;
    }

    /**
     * 能耗实时监控
     * @addressId 设备所属地址ID（1：2楼营业厅，2：8楼机房，3：9楼机房）
     * @typeId 1:年，2：月，3：日
     * @serialNumbers 设备编号集合
     * @return
     */
    @Override
    public RealEnergyMonitiorVo selectRealEnergyMonitiorEle(Integer typeId,List<String> serialNumbers,Date dateNow){
        RealEnergyMonitiorVo realEnergyMonitiorVo = new RealEnergyMonitiorVo();
        if(dateNow == null){
            dateNow = new Date();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dateNow);
        Integer year = calendar.get(Calendar.YEAR);
        Integer month = calendar.get(Calendar.MONTH)+1;
        Integer day = calendar.get(Calendar.DAY_OF_MONTH);
        Integer lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        List<CommonStatisVo> commonStatisVos = new ArrayList<>();
        List<CommonStatisVo> commonTodayStatisVos = new ArrayList<>();
        List<CommonStatisVo> commonMonthStatisVos = new ArrayList<>();
        DeviceLog deviceLog = new DeviceLog();
        deviceLog.setIdentity("ele");

        Map params = new HashMap<>();
        params.put("beginTime", year+"-01-01 00:00:00");
        params.put("endTime", year+"-12-31 23:59:59");
        deviceLog.setParams(params);
        List<EnergyConsumptionEleVo> energyConsumptionVos = tdDeviceLogDAO.selectRealEnergyMonitiorEleByYear(serialNumbers,deviceLog);
        if(energyConsumptionVos.size() > 0){
            Map<Timestamp,List<EnergyConsumptionEleVo>> elaMap = energyConsumptionVos.stream().collect(Collectors.groupingBy(EnergyConsumptionEleVo::getDateEnd));
            for (Timestamp timestamp : elaMap.keySet()) {
                List<EnergyConsumptionEleVo> dataList = elaMap.get(timestamp);
                BigDecimal value = BigDecimal.ZERO;
                for (EnergyConsumptionEleVo energyConsumptionEleVo : dataList) {
                    if(StringUtils.isBlank(energyConsumptionEleVo.getEnergyValueStart()) || StringUtils.isBlank(energyConsumptionEleVo.getEnergyValueEnd())){
                        continue;
                    }
                    value = value.add(getSubValue(energyConsumptionEleVo.getEnergyValueStart(),energyConsumptionEleVo.getEnergyValueEnd()));
                }
                String formattedDate = formatter.format(timestamp);
                LocalDate date = LocalDate.parse(formattedDate);
                if(date.getYear() != year){
                    continue;
                }
                System.out.println("按年查询ele："+date+"-"+value);
                CommonStatisVo commonStatisVo = new CommonStatisVo();
                commonStatisVo.setName(date.getMonthValue()+"月");
                commonStatisVo.setValueSort(date.getMonthValue());
                commonStatisVo.setValue(value.setScale(2,RoundingMode.HALF_UP));
                commonStatisVos.add(commonStatisVo);
                realEnergyMonitiorVo.setAnnualTotal(realEnergyMonitiorVo.getAnnualTotal().add(value).setScale(2,RoundingMode.HALF_UP));
                if(date.getYear() == year && month == date.getMonthValue()){
                    realEnergyMonitiorVo.setMonthTotal(value.setScale(2,RoundingMode.HALF_UP));
                }
            }
        }else{
            for(int i=1;i<=12;i++){
                CommonStatisVo commonStatisVo = new CommonStatisVo();
                commonStatisVo.setName(i+"月");
                commonStatisVo.setValueSort(i);
                commonStatisVo.setValue(BigDecimal.ZERO);
                commonStatisVos.add(commonStatisVo);
            }
        }

        int dayData = day;
        if(dayData > 1){
            dayData = (dayData -1);
        }
        params.put("beginTime", year+"-"+month+"-"+dayData+" 08:00:00");
        params.put("endTime", year+"-"+month+"-"+day+" 08:59:59");
        deviceLog.setParams(params);
        List<EnergyConsumptionEleVo> energyConsumptionVoByDayList = tdDeviceLogDAO.selectRealEnergyMonitiorEleByDay(serialNumbers,deviceLog);
        for (EnergyConsumptionEleVo energyConsumptionVo : energyConsumptionVoByDayList) {
            energyConsumptionVo.setDateStart(DateUtil.offsetHour(energyConsumptionVo.getDateStart(),14).toTimestamp());
            energyConsumptionVo.setDateEnd(DateUtil.offsetHour(energyConsumptionVo.getDateEnd(),14).toTimestamp());
        }
        if(energyConsumptionVoByDayList.size()>0){
            Map<Timestamp,List<EnergyConsumptionEleVo>> elaMap = energyConsumptionVoByDayList.stream().collect(Collectors.groupingBy(EnergyConsumptionEleVo::getDateEnd));
            for (Timestamp timestamp : elaMap.keySet()) {
                System.out.println("按日查询ele："+timestamp);
                List<EnergyConsumptionEleVo> dataList = elaMap.get(timestamp);
                BigDecimal value = BigDecimal.ZERO;
                for (EnergyConsumptionEleVo energyConsumptionEleVo : dataList) {
                    if(StringUtils.isBlank(energyConsumptionEleVo.getEnergyValueStart()) || StringUtils.isBlank(energyConsumptionEleVo.getEnergyValueEnd())){
                        continue;
                    }
                    value = value.add(getSubValue(energyConsumptionEleVo.getEnergyValueStart(),energyConsumptionEleVo.getEnergyValueEnd()));
                }
                String formattedDate = formatter.format(timestamp);
                LocalDate date = LocalDate.parse(formattedDate);

                Calendar hourCalendar = Calendar.getInstance();
                hourCalendar.setTime(timestamp);
                Integer hourOfDay = hourCalendar.get(Calendar.HOUR_OF_DAY)+1;
                if(hourCalendar.get(Calendar.DAY_OF_MONTH) > day){
                    continue;
                }
                realEnergyMonitiorVo.setTodayTotal(realEnergyMonitiorVo.getTodayTotal().add(value).setScale(2,RoundingMode.HALF_UP));
                CommonStatisVo commonStatisVo = new CommonStatisVo();
                commonStatisVo.setName(hourOfDay.toString());
                commonStatisVo.setValueSort(hourOfDay);
                if(hourOfDay > calendar.get(Calendar.HOUR_OF_DAY)){
                    commonStatisVo.setValue(BigDecimal.ZERO);
                }else{
                    commonStatisVo.setValue(value.setScale(2,RoundingMode.HALF_UP));
                }

                commonTodayStatisVos.add(commonStatisVo);
            }
        }else{
            for(int i=1;i<=23;i++){
                CommonStatisVo commonStatisVo = new CommonStatisVo();
                commonStatisVo.setName(i+"");
                commonStatisVo.setValueSort(i);
                commonStatisVo.setValue(BigDecimal.ZERO);
                commonTodayStatisVos.add(commonStatisVo);
            }
        }

        if(1==typeId){
            realEnergyMonitiorVo.getCommonStatisVoList().addAll(commonStatisVos);
        }else if(2==typeId){
            params.put("beginTime", year+"-"+month+"-01"+" 00:00:00");
            params.put("endTime", year+"-"+month+"-"+lastDay+" 23:59:59");
            deviceLog.setParams(params);
            List<EnergyConsumptionEleVo> energyConsumptionVoByMonthList = tdDeviceLogDAO.selectRealEnergyMonitiorEleByMonth(serialNumbers,deviceLog);
            for (EnergyConsumptionEleVo energyConsumptionVo : energyConsumptionVoByMonthList) {
                energyConsumptionVo.setDateStart(DateUtil.offsetHour(energyConsumptionVo.getDateStart(),16).toTimestamp());
                energyConsumptionVo.setDateEnd(DateUtil.offsetHour(energyConsumptionVo.getDateEnd(),16).toTimestamp());
            }
            if(energyConsumptionVoByMonthList.size()>0){
                Map<Timestamp,List<EnergyConsumptionEleVo>> elaMap = energyConsumptionVoByMonthList.stream().collect(Collectors.groupingBy(EnergyConsumptionEleVo::getDateEnd));
                for (Timestamp timestamp : elaMap.keySet()) {
                    List<EnergyConsumptionEleVo> dataList = elaMap.get(timestamp);
                    BigDecimal value = BigDecimal.ZERO;
                    for (EnergyConsumptionEleVo energyConsumptionEleVo : dataList) {
                        if(StringUtils.isBlank(energyConsumptionEleVo.getEnergyValueStart()) || StringUtils.isBlank(energyConsumptionEleVo.getEnergyValueEnd())){
                            continue;
                        }
                        value = value.add(getSubValue(energyConsumptionEleVo.getEnergyValueStart(),energyConsumptionEleVo.getEnergyValueEnd()));
                    }
                    String formattedDate = formatter.format(timestamp);
                    LocalDate date = LocalDate.parse(formattedDate);
                    if(date.getMonthValue() != month){
                        continue;
                    }
                    CommonStatisVo commonStatisVo = new CommonStatisVo();
                    commonStatisVo.setName(date.getDayOfMonth()+"日");
                    commonStatisVo.setValueSort(date.getDayOfMonth());
                    if(date.getDayOfMonth() > day){
                        commonStatisVo.setValue(BigDecimal.ZERO);
                    }else{
                        commonStatisVo.setValue(value.setScale(2,RoundingMode.HALF_UP));
                    }

                    commonMonthStatisVos.add(commonStatisVo);
                }
            }else{
                for(int i=1;i<=lastDay;i++){
                    CommonStatisVo commonStatisVo = new CommonStatisVo();
                    commonStatisVo.setName(i+"日");
                    commonStatisVo.setValueSort(i);
                    commonStatisVo.setValue(BigDecimal.ZERO);
                    commonMonthStatisVos.add(commonStatisVo);
                }
            }
            realEnergyMonitiorVo.getCommonStatisVoList().addAll(commonMonthStatisVos);
        }else if(3==typeId){
//            if(commonTodayStatisVos.size() > 0){
//                Map<String,List<CommonStatisVo>> todayMap = commonTodayStatisVos.stream().collect(Collectors.groupingBy(CommonStatisVo::getName));
//                List<CommonStatisVo> newData = new LinkedList<>();
//                for(int i=9;i<=32;i++){
//                    String name = ((i-8)+"");
//                    CommonStatisVo commonStatisVo = new CommonStatisVo();
//                    commonStatisVo.setName((i-8)+"");
//                    commonStatisVo.setValueSort(i-8);
//                    Integer hour = calendar.get(Calendar.HOUR_OF_DAY)+1;
//                    if(todayMap.get(name) != null && (i-8) < hour){
//                        commonStatisVo.setValue(todayMap.get(name).get(0).getValue());
//                    }else{
//                        commonStatisVo.setValue(BigDecimal.ZERO);
//                    }
//                    newData.add(commonStatisVo);
//                }
//                realEnergyMonitiorVo.setCommonStatisVoList(newData);
//            }else{
                realEnergyMonitiorVo.setCommonStatisVoList(commonTodayStatisVos);
//            }
        }
        realEnergyMonitiorVo.getCommonStatisVoList().sort((p1, p2) -> Integer.compare(p1.getValueSort(), p2.getValueSort()));
        return realEnergyMonitiorVo;
    }

    /**
     * 能耗实时监控
     * @addressId 设备所属地址ID（1：2楼营业厅，2：8楼机房，3：9楼机房）
     * @typeId 1:年，2：月，3：日
     * @serialNumbers 设备编号集合
     * @return
     */
    @Override
    public RealEnergyMonitiorVo selectRealEnergyMonitior(Integer typeId,List<String> serialNumbers,Date dateNow){
        RealEnergyMonitiorVo realEnergyMonitiorVo = new RealEnergyMonitiorVo();
        if(dateNow == null){
            dateNow = new Date();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dateNow);
        Integer year = calendar.get(Calendar.YEAR);
        Integer month = calendar.get(Calendar.MONTH)+1;
        Integer day = calendar.get(Calendar.DAY_OF_MONTH);
        Integer lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        List<CommonStatisVo> commonStatisVos = new ArrayList<>();
        List<CommonStatisVo> commonTodayStatisVos = new ArrayList<>();
        List<CommonStatisVo> commonMonthStatisVos = new ArrayList<>();
        DeviceLog deviceLog = new DeviceLog();
        deviceLog.setIdentity("ActiveEnergy");

        Map params = new HashMap<>();
        params.put("beginTime", year+"-01-01 00:00:00");
        params.put("endTime", year+"-12-31 23:59:59");
        deviceLog.setParams(params);
        List<EnergyConsumptionVo> energyConsumptionVos = tdDeviceLogDAO.selectRealEnergyMonitiorByYear(serialNumbers,deviceLog);
        if (null != energyConsumptionVos && energyConsumptionVos.size() > 0) {
            energyConsumptionVos.stream().forEach(d -> {
                System.out.println("按年查询："+d.getDateStart()+"-"+d.getDateEnd()+"-"+d.getEnergyValue());
                CommonStatisVo commonStatisVo = new CommonStatisVo();
                String formattedDate = formatter.format(d.getDateEnd());
                LocalDate date = LocalDate.parse(formattedDate);
                if(date.getYear() == year){
                    commonStatisVo.setName(date.getMonthValue()+"月");
                    commonStatisVo.setValueSort(date.getMonthValue());
                    commonStatisVo.setValue(d.getEnergyValue().setScale(2,RoundingMode.HALF_UP));
                    commonStatisVos.add(commonStatisVo);
                    if(date.getYear() == year && month == date.getMonthValue()){
                        realEnergyMonitiorVo.setMonthTotal(d.getEnergyValue().setScale(2,RoundingMode.HALF_UP));
                    }
                }
            });
        }else{
            for(int i=1;i<=12;i++){
                CommonStatisVo commonStatisVo = new CommonStatisVo();
                commonStatisVo.setName(i+"月");
                commonStatisVo.setValueSort(i);
                commonStatisVo.setValue(BigDecimal.ZERO);
                commonStatisVos.add(commonStatisVo);
            }
        }
        if(null != energyConsumptionVos && energyConsumptionVos.size()>0){
            energyConsumptionVos.stream().forEach(e->{
                if(null != e.getEnergyValue()){
                    realEnergyMonitiorVo.setAnnualTotal(realEnergyMonitiorVo.getAnnualTotal().add(e.getEnergyValue()).setScale(2,RoundingMode.HALF_UP));
                }
            });
        }

        int dayData = day;
        if(dayData > 1){
            dayData = (dayData -1);
        }
        params.put("beginTime", year+"-"+month+"-"+dayData+" 08:00:00");
        params.put("endTime", year+"-"+month+"-"+day+" 08:59:59");
        deviceLog.setParams(params);
        List<EnergyConsumptionVo> energyConsumptionVoByDayList = tdDeviceLogDAO.selectRealEnergyMonitiorByDay(serialNumbers,deviceLog);
        for (EnergyConsumptionVo energyConsumptionVo : energyConsumptionVoByDayList) {
            energyConsumptionVo.setDateStart(DateUtil.offsetHour(energyConsumptionVo.getDateStart(),14).toTimestamp());
            energyConsumptionVo.setDateEnd(DateUtil.offsetHour(energyConsumptionVo.getDateEnd(),14).toTimestamp());
        }
        if(null != energyConsumptionVoByDayList && energyConsumptionVoByDayList.size()>0){
            BigDecimal va = BigDecimal.ZERO;
            for (EnergyConsumptionVo energyConsumptionVo : energyConsumptionVoByDayList) {
                System.out.println("按日查询："+energyConsumptionVo.getDateStart()+"-"+energyConsumptionVo.getDateEnd()+"-"+energyConsumptionVo.getEnergyValue());
                Calendar hourCalendar = Calendar.getInstance();
                hourCalendar.setTime(energyConsumptionVo.getDateStart());
                Integer hourOfDay = hourCalendar.get(Calendar.HOUR_OF_DAY)+1;
                if(hourCalendar.get(Calendar.DAY_OF_MONTH) > day){
                    continue;
                }
                va = va.add(energyConsumptionVo.getEnergyValue());

                CommonStatisVo commonStatisVo = new CommonStatisVo();
                commonStatisVo.setName(hourOfDay.toString());
                commonStatisVo.setValueSort(hourOfDay);
                if(hourOfDay > calendar.get(Calendar.HOUR_OF_DAY)){
                    commonStatisVo.setValue(BigDecimal.ZERO);
                }else{
                    commonStatisVo.setValue(energyConsumptionVo.getEnergyValue().setScale(2,RoundingMode.HALF_UP));
                }

                commonTodayStatisVos.add(commonStatisVo);
            }
            realEnergyMonitiorVo.setTodayTotal(va.setScale(2,RoundingMode.HALF_UP));
        }else{
            for(int i=1;i<=23;i++){
                CommonStatisVo commonStatisVo = new CommonStatisVo();
                commonStatisVo.setName(i+"");
                commonStatisVo.setValueSort(i);
                commonStatisVo.setValue(BigDecimal.ZERO);
                commonTodayStatisVos.add(commonStatisVo);
            }
        }

        if(1==typeId){
            realEnergyMonitiorVo.getCommonStatisVoList().addAll(commonStatisVos);
        }else if(2==typeId){
            params.put("beginTime", year+"-"+month+"-01"+" 00:00:00");
            params.put("endTime", year+"-"+month+"-"+lastDay+" 23:59:59");
            deviceLog.setParams(params);
            List<EnergyConsumptionVo> energyConsumptionVoByMonthList = tdDeviceLogDAO.selectRealEnergyMonitiorByMonth(serialNumbers,deviceLog);
            for (EnergyConsumptionVo energyConsumptionVo : energyConsumptionVoByMonthList) {
                energyConsumptionVo.setDateStart(DateUtil.offsetHour(energyConsumptionVo.getDateStart(),16).toTimestamp());
                energyConsumptionVo.setDateEnd(DateUtil.offsetHour(energyConsumptionVo.getDateEnd(),16).toTimestamp());
            }
            if(null != energyConsumptionVoByMonthList && energyConsumptionVoByMonthList.size()>0){
                energyConsumptionVoByMonthList.stream().forEach(m->{
                    CommonStatisVo commonStatisVo = new CommonStatisVo();
                    String formattedDate = formatter.format(m.getDateStart());
                    LocalDate date = LocalDate.parse(formattedDate);
                    if(date.getMonthValue() == month){
                        commonStatisVo.setName(date.getDayOfMonth()+"日");
                        commonStatisVo.setValueSort(date.getDayOfMonth());
                        if(date.getDayOfMonth() > day){
                            commonStatisVo.setValue(BigDecimal.ZERO);
                        }else{
                            commonStatisVo.setValue(m.getEnergyValue().setScale(2,RoundingMode.HALF_UP));
                        }
                        commonMonthStatisVos.add(commonStatisVo);
                    }
                });
            }else{
                for(int i=1;i<=lastDay;i++){
                    CommonStatisVo commonStatisVo = new CommonStatisVo();
                    commonStatisVo.setName(i+"日");
                    commonStatisVo.setValueSort(i);
                    commonStatisVo.setValue(BigDecimal.ZERO);
                    commonMonthStatisVos.add(commonStatisVo);
                }
            }
            realEnergyMonitiorVo.getCommonStatisVoList().addAll(commonMonthStatisVos);
        }else if(3==typeId){
//            if(commonTodayStatisVos.size() > 0){
//                Map<String,List<CommonStatisVo>> todayMap = commonTodayStatisVos.stream().collect(Collectors.groupingBy(CommonStatisVo::getName));
//                List<CommonStatisVo> newData = new LinkedList<>();
//                for(int i=9;i<=32;i++){
//                    String name = ((i-8)+"");
//                    CommonStatisVo commonStatisVo = new CommonStatisVo();
//                    commonStatisVo.setName(name);
//                    commonStatisVo.setValueSort(i-8);
//                    Integer hour = calendar.get(Calendar.HOUR_OF_DAY)+1;
//                    if(todayMap.get(name) != null && (i-8) < hour){
//                        commonStatisVo.setValue(todayMap.get(name).get(0).getValue());
//                    }else{
//                        commonStatisVo.setValue(BigDecimal.ZERO);
//                    }
//                    newData.add(commonStatisVo);
//                }
//                realEnergyMonitiorVo.setCommonStatisVoList(newData);
//            }else{
                realEnergyMonitiorVo.setCommonStatisVoList(commonTodayStatisVos);
//            }
        }
        realEnergyMonitiorVo.getCommonStatisVoList().sort((p1, p2) -> Integer.compare(p1.getValueSort(), p2.getValueSort()));
        return realEnergyMonitiorVo;
    }

    /**
     * 能流监控
     * @dateNow 时间
     * @typeId 1:年，2：月，3：日
     * @serialNumbers 设备编号集合
     * @return
     */
    public EnergyFlowMonitorVo selectEnergyFlowMonitor(Integer typeId,List<String> serialNumbers,Date dateNow){
        EnergyFlowMonitorVo energyFlowMonitorVo = new EnergyFlowMonitorVo();
        if(dateNow == null){
            dateNow = new Date();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dateNow);
        Integer year = calendar.get(Calendar.YEAR);
        Integer month = calendar.get(Calendar.MONTH)+1;
        Integer day = calendar.get(Calendar.DAY_OF_MONTH)+1;
        Integer lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        List<CommonStatisVo> commonStatisVos = new ArrayList<>();
        List<CommonStatisVo> commonTodayStatisVos = new ArrayList<>();
        List<CommonStatisVo> commonMonthStatisVos = new ArrayList<>();
        DeviceLog deviceLog = new DeviceLog();
        deviceLog.setIdentity("ActiveEnergy");

        AtomicReference<BigDecimal> monthTotal = new AtomicReference<>(BigDecimal.ZERO);
        AtomicReference<BigDecimal> yearTotal = new AtomicReference<>(BigDecimal.ZERO);
        AtomicReference<BigDecimal> dayTotal = new AtomicReference<>(BigDecimal.ZERO);

        Map params = new HashMap<>();
        params.put("beginTime", year+"-01-01 00:00:00");
        params.put("endTime", year+"-12-31 23:59:59");
        deviceLog.setParams(params);
        List<EnergyConsumptionVo> energyConsumptionVos = tdDeviceLogDAO.selectRealEnergyMonitiorByYear(serialNumbers,deviceLog);
        if (null != energyConsumptionVos && energyConsumptionVos.size() > 0) {
            energyConsumptionVos.stream().forEach(d -> {
                CommonStatisVo commonStatisVo = new CommonStatisVo();
                String formattedDate = formatter.format(d.getDateStart());
                LocalDate date = LocalDate.parse(formattedDate);
                commonStatisVo.setName(date.getMonthValue()+"月");
                commonStatisVo.setValue(d.getEnergyValue());
                commonStatisVos.add(commonStatisVo);
                if(date.getYear() == year && month == date.getMonthValue()){
                    monthTotal.set(d.getEnergyValue());
                }
            });
        }else{
            for(int i=1;i<=12;i++){
                CommonStatisVo commonStatisVo = new CommonStatisVo();
                commonStatisVo.setName(i+"月");
                commonStatisVo.setValue(BigDecimal.ZERO);
                commonStatisVos.add(commonStatisVo);
            }
        }
        if(null != energyConsumptionVos && energyConsumptionVos.size()>0){
            energyConsumptionVos.stream().forEach(e->{
                if(null != e.getEnergyValue()){
                    yearTotal.set(yearTotal.get().add(e.getEnergyValue()));
                }
            });
        }

        int dayData = day;
        if(dayData > 1){
            dayData = (dayData -1);
        }
        params.put("beginTime", year+"-"+month+"-"+dayData+" 08:00:00");
        params.put("endTime", year+"-"+month+"-"+day+" 08:59:59");
        deviceLog.setParams(params);
        List<EnergyConsumptionVo> energyConsumptionVoByDayList = tdDeviceLogDAO.selectRealEnergyMonitiorByDay(serialNumbers,deviceLog);
        for (EnergyConsumptionVo energyConsumptionVo : energyConsumptionVoByDayList) {
            energyConsumptionVo.setDateStart(DateUtil.offsetHour(energyConsumptionVo.getDateStart(),14).toTimestamp());
            energyConsumptionVo.setDateEnd(DateUtil.offsetHour(energyConsumptionVo.getDateEnd(),14).toTimestamp());
        }
        if(null != energyConsumptionVoByDayList && energyConsumptionVoByDayList.size()>0){
            BigDecimal va = BigDecimal.ZERO;
            for (EnergyConsumptionVo energyConsumptionVo : energyConsumptionVoByDayList) {
                System.out.println("按日查询flow："+energyConsumptionVo.getDateStart()+"-"+energyConsumptionVo.getDateEnd()+"-"+energyConsumptionVo.getEnergyValue());
                Calendar hourCalendar = Calendar.getInstance();
                hourCalendar.setTime(energyConsumptionVo.getDateStart());
                Integer hourOfDay = hourCalendar.get(Calendar.HOUR_OF_DAY)+1;
                if(hourCalendar.get(Calendar.DAY_OF_MONTH) > day){
                    continue;
                }
                va = va.add(energyConsumptionVo.getEnergyValue());

                CommonStatisVo commonStatisVo = new CommonStatisVo();
                commonStatisVo.setName(hourOfDay.toString());
                commonStatisVo.setValueSort(hourOfDay);
                if(hourOfDay > calendar.get(Calendar.HOUR_OF_DAY)){
                    commonStatisVo.setValue(BigDecimal.ZERO);
                }else{
                    commonStatisVo.setValue(energyConsumptionVo.getEnergyValue().setScale(2,RoundingMode.HALF_UP));
                }

                commonTodayStatisVos.add(commonStatisVo);
            }
            dayTotal.set(va.setScale(2,RoundingMode.HALF_UP));
        }else{
            for(int i=1;i<=23;i++){
                CommonStatisVo commonStatisVo = new CommonStatisVo();
                commonStatisVo.setName(i+"");
                commonStatisVo.setValueSort(i);
                commonStatisVo.setValue(BigDecimal.ZERO);
                commonTodayStatisVos.add(commonStatisVo);
            }
        }

        if(1==typeId){
            energyFlowMonitorVo.setElectricTotal(yearTotal.get());
            energyFlowMonitorVo.setEnergyTotal(yearTotal.get());
            BigDecimal carbonTotal = yearTotal.get().multiply(new BigDecimal("0.785")).setScale(2,RoundingMode.HALF_UP);
            energyFlowMonitorVo.setCarbonTotal(carbonTotal);
            energyFlowMonitorVo.getCommonStatisVoList().addAll(commonStatisVos);
        }else if(2==typeId){
            energyFlowMonitorVo.setElectricTotal(monthTotal.get());
            energyFlowMonitorVo.setEnergyTotal(monthTotal.get());
            BigDecimal carbonTotal = monthTotal.get().multiply(new BigDecimal("0.785")).setScale(2,RoundingMode.HALF_UP);
            energyFlowMonitorVo.setCarbonTotal(carbonTotal);

            params.put("beginTime", year+"-"+month+"-01"+" 00:00:00");
            params.put("endTime", year+"-"+month+"-"+lastDay+" 23:59:59");
            deviceLog.setParams(params);
            List<EnergyConsumptionVo> energyConsumptionVoByMonthList = tdDeviceLogDAO.selectRealEnergyMonitiorByMonth(serialNumbers,deviceLog);
            for (EnergyConsumptionVo energyConsumptionVo : energyConsumptionVoByMonthList) {
                energyConsumptionVo.setDateStart(DateUtil.offsetHour(energyConsumptionVo.getDateStart(),16).toTimestamp());
                energyConsumptionVo.setDateEnd(DateUtil.offsetHour(energyConsumptionVo.getDateEnd(),16).toTimestamp());
            }
            if(null != energyConsumptionVoByMonthList && energyConsumptionVoByMonthList.size()>0){
                energyConsumptionVoByMonthList.stream().forEach(m->{
                    CommonStatisVo commonStatisVo = new CommonStatisVo();
                    String formattedDate = formatter.format(m.getDateStart());
                    LocalDate date = LocalDate.parse(formattedDate);
                    commonStatisVo.setName(date.getDayOfMonth()+"日");
                    if(date.getDayOfMonth() > day){
                        commonStatisVo.setValue(BigDecimal.ZERO);
                    }else{
                        commonStatisVo.setValue(m.getEnergyValue());
                    }
                    commonMonthStatisVos.add(commonStatisVo);
                });
            }else{
                for(int i=1;i<=lastDay;i++){
                    CommonStatisVo commonStatisVo = new CommonStatisVo();
                    commonStatisVo.setName(i+"日");
                    commonStatisVo.setValueSort(i);
                    commonStatisVo.setValue(BigDecimal.ZERO);
                    commonMonthStatisVos.add(commonStatisVo);
                }
            }
            energyFlowMonitorVo.getCommonStatisVoList().addAll(commonMonthStatisVos);
        }else if(3==typeId){
            energyFlowMonitorVo.setElectricTotal(dayTotal.get());
            energyFlowMonitorVo.setEnergyTotal(dayTotal.get());
            BigDecimal carbonTotal = dayTotal.get().multiply(new BigDecimal("0.785")).setScale(2,RoundingMode.HALF_UP);
            energyFlowMonitorVo.setCarbonTotal(carbonTotal);

//            if(commonTodayStatisVos.size() > 0){
//                Map<String,List<CommonStatisVo>> todayMap = commonTodayStatisVos.stream().collect(Collectors.groupingBy(CommonStatisVo::getName));
//                List<CommonStatisVo> newData = new LinkedList<>();
//                for(int i=9;i<=32;i++){
//                    String name = ((i-8)+"");
//                    CommonStatisVo commonStatisVo = new CommonStatisVo();
//                    commonStatisVo.setName((i-8)+"");
//                    commonStatisVo.setValueSort(i-8);
//                    Integer hour = calendar.get(Calendar.HOUR_OF_DAY)+1;
//                    if(todayMap.get(name) != null && (i-8) < hour){
//                        commonStatisVo.setValue(todayMap.get(name).get(0).getValue());
//                    }else{
//                        commonStatisVo.setValue(BigDecimal.ZERO);
//                    }
//                    newData.add(commonStatisVo);
//                }
//                energyFlowMonitorVo.setCommonStatisVoList(newData);
//            }else{
                energyFlowMonitorVo.setCommonStatisVoList(commonTodayStatisVos);
//            }
        }
        return energyFlowMonitorVo;
    }

    @Override
    public String getLeastDeviceData(String number,String identity) {
        return tdDeviceLogDAO.getLeastDeviceData(number,identity);
    }

    @Override
    public Long monitiorDataCheck() {
        return tdDeviceLogDAO.monitiorDataCheck();
    }
}
